#ifndef _ENGINE_H_
#define _ENGINE_H_

#include <model.h>

#define MSG_ENGINE_UPDATE_SENSOR  0
#define MSG_ENGINE_TICK           1
#define MSG_ENGINE_SPEED          2
#define MSG_ENGINE_WHERE          3
#define MSG_ENGINE_REVERSE        4
#define MSG_ENGINE_NEXT_LANDMARK  5
#define MSG_ENGINE_PLAY           6

#define ENGINE_LEARNING_RATE      15
#define MAX_SENSOR_NBRS           6

#define ENGINE_RUNNING      0
#define ENGINE_STOPPING     1
#define ENGINE_STOPPED      2
#define ENGINE_LOST         3

typedef struct __engine {
  int train_number;               // number of train
  // speed state
  int speed;                      // current speed (0-14)
  int last_speed;                 // last speed (0-14)
  // expected (extrapolated) state
  int expect_dist_prev_sensor;    // expected position from last sensor, um
  int expect_dist_prev;           // expected position from last landmark, um
  int expect_prev;                // expected previous landmark
  int expect_curr;                // expected current landmark
  int expect_next;                // expected next landmark
  int expect_dist_next;           // distance to next expected landmark
  // actual (measured) state
  int actual_curr;                // actual current landmark
  int actual_speed_prev;          // train speed (0-14) at last sensor
  int actual_ticks_prev;          // time at last sensor, ticks
  int state;
  // stopping parameters
  int stopping_vel;               // stopping velocity
  int stopping_decel;             // stopping deceleration
  int distance_to_stop;
  // predictions
  track_edge first_prediction;    // first predicted sensor
  track_edge second_prediction;   // second predicted sensor
  // velocity/stop distance tables
  int vel_table_accel[15];        // velocity table (accel)
  int vel_table_decel[15];        // velocity table (decel)
  int stop_dist_accel[15];        // stop distance (accel)
  int stop_dist_decel[15];        // stop distance (decel)
  // ticks since last print
  int last_print_ticks;
  // line to print status on
  int status_line;
} engine;

void EngineManager();
int WhereAmI(int train);
int NextExpectedLandmark(int train);
void UpdateTrainReverse(int train);
void Play(int train, int opponent);

#endif
